package com.vxdata.utils.modules.word.freemarker;


import com.alibaba.fastjson2.JSONArray;
import com.vxdata.common.utils.StringUtils;

import com.vxdata.utils.modules.word.freemarker.vo.DatacenterApiResource;
import com.vxdata.utils.modules.word.freemarker.vo.DatacenterResourceMetadata;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class WordUtil {


    /**
     * 存放模板的目录
     */
    @Value("${wordTemplatePath}")
    private String wordTemplatePath;


    /**
     * 生成 word 文档方法
     *
     * @param dataMap      要填充的数据
     * @param templateName 模版名称.ftl (只有名称)
     * @param fileName     要输出的文件路径 xxx/xxx/xxx.doc
     * @throws Exception 抛出的异常
     */
    public void createWordLocal(Map<String, Object> dataMap, String templateName, String fileName) throws Exception {
        // 设置FreeMarker的版本和编码格式
        Configuration configuration = new Configuration(new Version("2.3.28"));
        configuration.setDefaultEncoding("UTF-8");

        // 设置FreeMarker生成Word文档所需要的模板的路径
        configuration.setDirectoryForTemplateLoading(new File(wordTemplatePath));
        // 此处把模版文件都放在 resources 下的 templates 中
        // configuration.setClassForTemplateLoading(WordUtils.class, "/templates");

        // 设置FreeMarker生成Word文档所需要的模板
        Template tem = configuration.getTemplate(templateName, "UTF-8");
        // 创建一个Word文档的输出流
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(fileName)), StandardCharsets.UTF_8));
        // FreeMarker使用Word模板和数据生成Word文档
        tem.process(dataMap, out);
        out.flush();
        out.close();
    }

    public void createWordResponse(HttpServletResponse response, Map<String, Object> dataMap, String templateName, String fileName) throws Exception {
        // 设置FreeMarker的版本和编码格式
        Configuration configuration = new Configuration(new Version("2.3.28"));
        configuration.setDefaultEncoding("UTF-8");

        // 设置FreeMarker生成Word文档所需要的模板的路径
        configuration.setDirectoryForTemplateLoading(new File(wordTemplatePath));
        // 此处把模版文件都放在 resources 下的 templates 中
        // configuration.setClassForTemplateLoading(WordUtils.class, "/templates");

        // 设置FreeMarker生成Word文档所需要的模板
        Template tem = configuration.getTemplate(templateName, "UTF-8");
        // 创建一个Word文档的输出流
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-Type", "application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".doc", "UTF-8"));
        OutputStream outputStream = response.getOutputStream();
        Writer out = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
        // FreeMarker使用Word模板和数据生成Word文档
        tem.process(dataMap, out);
        out.flush();
        out.close();
    }

    private Map<String, Object> getDataMap(DatacenterResourceMetadata metadata, DatacenterApiResource api) {
        Map<String, Object> map = new HashMap<>();
        map.put("title", api.getTitle());
        map.put("resourceCode", metadata.getResourceCode() != null ? metadata.getResourceCode() : "");
        map.put("resourceSummary", metadata.getResourceSummary() != null ? metadata.getResourceSummary() : "");
        map.put("resourceProvider", metadata.getResourceProvider() != null ? metadata.getResourceProvider() : "");
        map.put("resourceProviderCode", metadata.getResourceProviderCode() != null ? metadata.getResourceProviderCode() : "");
        map.put("resourceSourceSystem", metadata.getResourceSourceSystem() != null ? metadata.getResourceSourceSystem() : "");
        map.put("resourceSaveFormat", metadata.getResourceSaveFormat() != null ? metadata.getResourceSaveFormat() : "");
        map.put("publishDate", metadata.getPublishDate() != null ? DateTimeFormatter.ofPattern("yyyy-MM-dd").format(metadata.getPublishDate()) : "");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        map.put("updateTime", api.getUpdateTime() != null ? dateFormat.format(api.getUpdateTime()) : "");
        map.put("url", api.getUrl() != null ? api.getUrl() : "");
        map.put("requestMethod", api.getRequestMethod() != null ? api.getRequestMethod() : "");
        map.put("contentType", api.getContentType() != null ? api.getContentType() : "");
        map.put("responseFormat", api.getResponseFormat() != null ? api.getResponseFormat() : "");
        if (api.getModel() != 6) {
            map.put("paramVoList", getParamVoList(api));
            map.put("resultVoList", getResultVoMapList(api));
        } else {
            map.put("param", api.getRequestParam());
            map.put("result", api.getResponseParam());
        }

        return map;
    }


    private List<Map<String, Object>> getResultVoMapList(DatacenterApiResource api) {
        List<WordResultVo> excelListVos = new ArrayList<>();
        String responseParam = api.getResponseParam();
        if (StringUtils.isNotEmpty(responseParam)) {
            excelListVos = JSONArray.parseArray(responseParam, WordResultVo.class);
        }
        // 转成 List<Map> 结构
        List<Map<String, Object>> excelList = new ArrayList<>();
        if (excelListVos != null && excelListVos.size() > 0) {
            for (WordResultVo excelResultVo : excelListVos) {
                Map<String, Object> map = new HashMap<>();
                map.put("name", excelResultVo.getName() != null ? excelResultVo.getName() : "");
                map.put("type", excelResultVo.getType() != null ? excelResultVo.getType() : "");
                map.put("size", excelResultVo.getSize() != null ? excelResultVo.getSize() : "");
                map.put("comment", excelResultVo.getComment() != null ? excelResultVo.getComment() : "");
                excelList.add(map);
            }
        }
        return excelList;
    }

    private List<Map<String, Object>> getParamVoList(DatacenterApiResource api) {
        // 向导模式
        List<WordParamVo> paramVoList = new ArrayList<>();
        if (api.getModel() == 0) {
            String requestParam = api.getRequestParam();
            if (StringUtils.isNotEmpty(requestParam)) {
                paramVoList = JSONArray.parseArray(requestParam, WordParamVo.class);
            }
            WordParamVo pageNo = new WordParamVo();
            pageNo.setName("pageNo");
            pageNo.setType("INT");
            pageNo.setIsMust("否");
            pageNo.setExample("1");
            pageNo.setDefaultValue("1");
            pageNo.setComment("当前页码");
            paramVoList.add(pageNo);

            WordParamVo pageSize = new WordParamVo();
            pageSize.setName("pageSize");
            pageSize.setType("INT");
            pageSize.setIsMust("否");
            pageSize.setExample("2000");
            pageSize.setDefaultValue("2000");
            pageSize.setComment("每页条数");
            paramVoList.add(pageSize);
        }

        List<Map<String, Object>> excelList = new ArrayList<>();
        if (paramVoList != null && paramVoList.size() > 0) {
            for (WordParamVo recordVo : paramVoList) {
                Map<String, Object> map = new HashMap<>();
                map.put("name", recordVo.getName() != null ? recordVo.getName() : "");
                map.put("type", recordVo.getType() != null ? recordVo.getType() : "");
                map.put("operator", recordVo.getOperator() != null ? recordVo.getOperator() : "");
                map.put("isMust", recordVo.getIsMust() != null ? recordVo.getIsMust() : "");
                map.put("example", recordVo.getExample() != null ? recordVo.getExample() : "");
                map.put("defaultValue", recordVo.getDefaultValue() != null ? recordVo.getDefaultValue() : "");
                map.put("comment", recordVo.getComment() != null ? recordVo.getComment() : "");
                excelList.add(map);
            }
        }
        return excelList;
    }

    @Data
    private static class WordParamVo {
        // 名称
        private String name;
        // 类型
        private String type;
        // 操作符
        private String operator;
        // 是否必填
        private String isMust;
        // 示例值
        private String example;
        // 默认值
        private String defaultValue;
        // 说明
        private String comment;
    }


    @Data
    private static class WordResultVo {
        // 名称
        private String name;
        // 类型
        private String type;
        // 长度
        private String size;
        // 说明
        private String comment;
    }


}
